﻿#region Copyright

// All Material Copyright © 2008-2010 Dynamic Concepts Development Corp., All Rights Reserved
// 
// For further information please contact SoftwareSupport@dynconcepts.com
// 
// Dynamic Concepts Development Corp.  311 W 57th St. Suite #422, New York, NY 10019

#endregion

#region Using References

using System;
using System.Collections.Generic;

#endregion

namespace DynConDev.CorpLib.CommandLineParser
{
    public enum OptionType
    {
        Required,
        Optional
    }

    public abstract class CommandOptionHandlerDictionary
    {
        public abstract bool Execute<TCommandProcessor>(TCommandProcessor instance, IEnumerable<Option> options)
            where TCommandProcessor : CommandProcessor;
    }

    public class CommandOptionHandlerDictionary<TCommandProcessor> : CommandOptionHandlerDictionary
        where TCommandProcessor : CommandProcessor
    {
        private readonly Dictionary<String, Func<TCommandProcessor, string, bool>> r_RegisteredHandlers =
            new Dictionary<string, Func<TCommandProcessor, string, bool>>();

        private readonly List<String> r_RequiredOptions = new List<String>();

        public void Register(string optionName, Func<TCommandProcessor, string, bool> handler, OptionType optionType)
        {
            r_RegisteredHandlers.Add(optionName.ToUpperInvariant(), handler);
            if (optionType == OptionType.Required)
                r_RequiredOptions.Add(optionName);
        }

        public override bool Execute<TCommandProcessorInstance>(TCommandProcessorInstance instance,
                                                                IEnumerable<Option> options)
        {
            List<String> requiredOptions = new List<String>(r_RequiredOptions);
            foreach (Option option in options)
            {
                string name = option.Name.ToUpperInvariant();
                Func<TCommandProcessor, string, bool> func;
                if (!r_RegisteredHandlers.TryGetValue(name, out func))
                    return false;
                string value = option.Value;
                TCommandProcessor typedInstance = instance as TCommandProcessor;
                bool result = func(typedInstance, value);
                if (result == false)
                    return false;
                requiredOptions.Remove(option.Name);
            }
            if (requiredOptions.Count > 0)
            {
                Console.WriteLine("Required Options NOT supplied:...");
                foreach (String option in requiredOptions)
                {
                    Console.WriteLine("\t{0}", option);
                }
                return false;
            }
            return true;
        }
    }
}